package org.itboys.mobile.service.mysql.front;


import org.apache.commons.lang3.StringUtils;
import org.itboys.commons.ErrorException;
import org.itboys.commons.utils.tools.ListUtil;
import org.itboys.commons.utils.tools.LongUtil;

import org.itboys.mobile.common.SundayCommonConstants;
import org.itboys.mobile.dao.pay.SundayPayConfigMapper;
import org.itboys.mobile.dto.pay.SundayPayDto;
import org.itboys.mobile.entity.mongo.SundayCid;
import org.itboys.mobile.entity.mysql.order.SundayOrder;
import org.itboys.mobile.entity.mysql.pay.SundayPay;
import org.itboys.mobile.entity.mysql.pay.SundayPayConfig;

import org.itboys.mobile.util.NumberUtil;
import org.itboys.mobile.util.getui.GeTuiUtil;
import org.itboys.mysql.service.BaseMySqlService;
import org.itboys.pay.alipay.AlipayMobileService;
import org.itboys.pay.alipay.AlipayWapResult;
import org.itboys.pay.tools.XMLUtil;
import org.itboys.pay.weixin.AppPaySignTool;
import org.itboys.pay.weixin.WXPayNotify;
import org.itboys.pay.weixin.WeixinPayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.DataInputStream;
import java.math.BigDecimal;
import java.util.*;


/**
 * 作者：jiangxiong
 * 日期：2017年5月8日
 * 联系方式 ：empty90911@126.com
 * 描述：圣代_支付_service_mobile
 */
@Service
public class SundayMobilePayService extends BaseMySqlService<SundayPay> {


	public static String PAY_CALLBACK_URL_wechat= "https://admin.igoec.com/sunday/mobile/pay/callback/wechat";
	public static String PAY_CALLBACK_URL_alipay= "https://admin.igoec.com/sunday/mobile/pay/callback/alipay";

	@Autowired
	private SundayFrontOrderService orderService;
	@Autowired
	private SundayPayConfigMapper payConfigMapper;




	/**
	 * 预支付：判断订单中数据是否合法以及返回支付需要的参数
	 * @param payType 1,支付宝，2，微信
	 * @param orderIds 订单ID集合。例如:1,2,3,4
	 * @param type，1,订单支付，2余额充值
	 * @return
	 */
	public SundayPayDto preparePay(Integer payType, List<Long> orderIds, Integer type){
		//1,声明返回结果
		SundayPayDto payDto =null;
		//传入第三方的外部订单号
		String orderNo= NumberUtil.generateNumber("PREPAY");
		//支付描述
		String remark="";
		if(type==1){
			remark="爱购梵品，订单消费";
		}else if(type==2){
			remark="爱购梵品，余额充值";
		}
		//本次需要支付的金额
		Double payAmount=0.00;
		//本次需要操作的订单（余额充值记录）ids
		StringBuilder orderIdsStr = new StringBuilder();

	/*	//支付宝返回结果
		String alipayAccountNo=null;
		String alipayPid=null;
		String alipayPrivateKey=null;
		String alipayCallback=null;
		//微信返回结果
		 String appId=null;
		 String timeStamp=null;
		 String nonceStr=null;
		 String paySign=null;
		 String package_="Sign=WXPay";//固定值。
		 String signType=null;*/

		 Map<String,Object> param = new HashMap<String,Object>();
		//2，根据支付类型。查询相关项目业务，统计支付金额
		  //2.1，订单支付
		if(type==1){
			param.clear();
			param.put("ids",orderIds);
			List<SundayOrder> orders = orderService.select(param);
			for(SundayOrder order:orders){
				//logger.info("-----订单编号"+order.getOrderNo()+",实付金额="+order.getPayAmount());
				payAmount+=order.getPayAmount().doubleValue();
				//存放需要订单ID时，用_隔开;
				orderIdsStr.append(order.getId()+"_");
			}

		}

		//2.2，余额充值
		if(type==2){
			/*param.clear();
			param.put("ids",orderIds);
			List<KitchenIncomeRecord> incomeRecords=incomeRecordMapper.select(param);
			for(KitchenIncomeRecord incomeRecord:incomeRecords){
				//2017年6月15日，充值赠送的不需要支付
				if(incomeRecord.getType()== SundayCommonConstants.income_record_type_charge){
					payAmount+=incomeRecord.getAmount().doubleValue();
				}
				//存放需要充值记录ID时，用_隔开;
				orderIdsStr.append(incomeRecord.getId()+"_");
			}*/
		}

		//3，内部业务校验（例如校验余额，优惠券，商品库存等等）


		//4，返回移动端需要的支付参数
		param.clear();
		SundayPayConfig payConfig =null;
		List<SundayPayConfig> payConfigs =payConfigMapper.select(param);
		//4.1,返回支付宝参数
		if(payType==1){
			for(SundayPayConfig p:payConfigs){
				if(p.getType()== SundayCommonConstants.pay_type_alipay){
					payConfig=p;
				}
			}
			if(payConfig==null){
				throw new ErrorException("预支付失败，支付宝未配置支付信息");
			}
			String alipayResult =null;
			try {
				//获取平台的支付宝PID
				//商户私钥
				String alipayAppPrivatekey=payConfig.getAlipayAppPrivateKey();
				logger.info("--支付宝商户私钥--"+alipayAppPrivatekey);
				//商户公钥
				String alipayAppPublicKey=payConfig.getAlipayAppPublicKey();
				logger.info("--支付宝商户公钥--"+alipayAppPublicKey);
				alipayResult= AlipayMobileService.newAppPay(
						payConfig.getAlipayAppId(),payAmount.toString(),orderNo,
						PAY_CALLBACK_URL_alipay,alipayAppPrivatekey,
						remark, remark, alipayAppPublicKey);
				//AlipayMobileService.t
			} catch (Exception e) {
				logger.info("预支付，支付宝，内部组装参数错误");
				e.printStackTrace();

			}


			payDto=new SundayPayDto(orderNo, payAmount.toString(),remark,alipayResult );
		//微信支付
		}else if(payType==2){
			for(SundayPayConfig p:payConfigs){
				if(p.getType()== SundayCommonConstants.pay_type_wechatpay_open){
					payConfig=p;
				}
			}
			if(payConfig==null){
				throw new ErrorException("预支付失败，微信未配置支付信息");
			}
			//WeixinPaySignTool tool=null;
				AppPaySignTool tool=null;
			try {
			/*	tool=WeixinPayUtils.paySign(String appid, String mchId,
						String openid, String outTradeNo,
						String spbillCreateIp, String tradeType, String body,
						String totalFee, String notifyUrl, String productId, String ke)*/

			String payAmountStr=String.valueOf(new BigDecimal(payAmount*100).setScale(0,BigDecimal.ROUND_HALF_UP));
			//	logger.info("---实付金额222222222222--"+payAmountStr);
				/*tool=WeixinPayUtils.paySign(
						payConfig.getWeChatAppId(),
						payConfig.getWeChatMchId(),
						null,
						orderNo,
						"139.196.150.224",
						"APP",
						remark,
						payAmountStr,
						PAY_CALLBACK_URL_wechat,
						"1",
						payConfig.getWeChatApi());*/

			tool= WeixinPayUtils.appPay(payConfig.getWeChatAppId(),
						payConfig.getWeChatMchId(),
						orderNo, 	"139.196.150.224",
						"APP", payAmountStr,PAY_CALLBACK_URL_wechat, payConfig.getWeChatApi());
				//logger.info("--支付-微信-tool"+tool);
			//return tool;




			payDto=new SundayPayDto(
						orderNo,payAmountStr, remark,
						tool.getAppid(), tool.getTimestamp(), tool.getNoncestr(),tool.getSign(),
						"Sign=WXPay", "MD5",payConfig.getWeChatMchId(),tool.getPrepayid());

			} catch (Exception e) {
				e.printStackTrace();
				throw new ErrorException("微信预支付失败");
			}
		}
		//5，本地存储预支付的结果，便于第三方支付回掉时执行业务逻辑
		SundayPay pay = new SundayPay(orderNo,orderIdsStr.substring(0,orderIdsStr.length()-1).toString(),
				new BigDecimal(payAmount).setScale(2,BigDecimal.ROUND_HALF_UP),type,remark);
		super.insert(pay);


		return payDto;
	}

	/**
	 * 支付宝支付回掉
	 * @param request
	 * @param
	 */
	@Transactional
	public AlipayWapResult callback_alipay(HttpServletRequest request){
		AlipayWapResult alipayWapResult=new AlipayWapResult();
		//1，检验签名和请求来源
		Map<String,Object> param = new HashMap<String,Object>();
		param.put("type", SundayCommonConstants.pay_type_alipay);
		List<SundayPayConfig> payConfigs =payConfigMapper.select(param);
		//支付宝公钥
		String publicKey = "";
		if(ListUtil.isNull(payConfigs)){
			return alipayWapResult;
		}
		//支付宝公钥
		publicKey=payConfigs.get(0).getAlipayPublicKey();
		logger.info("--支付宝公钥--"+publicKey);
		try {
			alipayWapResult = AlipayMobileService.notifyResult(request,publicKey);
		}catch (Exception e){
			e.printStackTrace();
			logger.info("支付-支付宝-回掉-签名验证错误。"+e);
			return alipayWapResult;
		}
		//验证成功或失败的标识
		boolean  verify_result= alipayWapResult.isVerify_result();

		String  trade_status=alipayWapResult.getTrade_status();
		String  out_trade_no=alipayWapResult.getOut_trade_no();
		String trade_no = alipayWapResult.getTrade_no();
		String notify_data=alipayWapResult.getNotify_data();
		BigDecimal  price =alipayWapResult.getPrice();
		logger.info("支付-支付宝-回掉-信息.trade_status="+trade_status+
				",out_trade_no="+out_trade_no+
				",trade_no="+trade_no+
				",notify_data="+notify_data+
				",price="+price+
				",verify_result="+verify_result);
		if(!verify_result){
			logger.error("支付-支付宝-回掉-签名验证失败。");
			return alipayWapResult;
		}

		//查询本地预支付记录
		param.clear();
		if(StringUtils.isEmpty(out_trade_no)){
			logger.error("支付-支付宝-open-回掉-外部订单为空");
			alipayWapResult.setVerify_result(false);
			return alipayWapResult;
		}
		param.put("orderNo",out_trade_no);
		List<SundayPay> pays = super.select(param);
		if(ListUtil.isNull(pays)){
			logger.error("支付-支付宝-回掉-本地无预支付记录，返回");

			alipayWapResult.setVerify_result(false);
			return alipayWapResult;
		}
		SundayPay pay=pays.get(0);
		//2，项目内部逻辑。校验支付金额
		//2.1,订单消费
		if(pay.getType()== SundayCommonConstants.pay_order_type_order){
			List<Long> orderIds = new ArrayList<Long>();
			for(String orderIdStr:pay.getOrderIds().split("_")){
				orderIds.add(Long.valueOf(orderIdStr));
			}
			if(ListUtil.isNull(orderIds)){
				logger.error("支付-支付宝-回掉-本地预支付记录无订单参数，返回");
				alipayWapResult.setVerify_result(false);
				return alipayWapResult;
			}
			param.clear();
			param.put("status", SundayCommonConstants.ORDER_STATUS_DFK);
			param.put("ids",orderIds);
			List<SundayOrder> orders =orderService.select(param);
			//校验付款金额
			Double orderPayAmount = 0.00;
			for(SundayOrder order:orders){
				orderPayAmount+=order.getPayAmount().doubleValue();
			}
			if(price.compareTo(new BigDecimal(orderPayAmount).setScale(2,BigDecimal.ROUND_HALF_UP))==-1){
				logger.error("支付-支付宝-回掉-订单实际支付金额错误，应支付金额="+orderPayAmount+"，实际支付金额="+price+","+"预支付订单编号="+out_trade_no);
				alipayWapResult.setVerify_result(false);
				return alipayWapResult;
			}
			//更改订单状态
			List<Long> memberIds =new ArrayList<Long>();
			for(SundayOrder order:orders){
				//避免重复回掉
				if(order.getStatus()== SundayCommonConstants.ORDER_STATUS_DFK){
					Integer status= SundayCommonConstants.ORDER_STATUS_DFH;
					logger.info("支付-支付宝-回掉-当前支付订单"+order.getOrderNo());
					if(order.getType()==SundayCommonConstants.type_pintuan){
						//0单独购买，1参与别人的，2自己开团
						if(order.getTeamIsJoin()==0){
							status=SundayCommonConstants.ORDER_STATUS_DFH;//待发货
						}else{
							status=SundayCommonConstants.ORDER_STATUS_DPT;//待拼团；
						}
					}else{
						//2018年2月24日，根据配送方式判断
						//门店配送为待配送
						if(order.getSendType()==SundayCommonConstants.send_type_send){
							status=SundayCommonConstants.ORDER_STATUS_DFH;//待发货
							//自提为配送中
						}else if(order.getSendType()==SundayCommonConstants.send_type_self){
							status=SundayCommonConstants.ORDER_STATUS_PSZ;//配送中
						}
					}
					order.setStatus(status);
					order.setPayTime(new Date());
					order.setPayNo(trade_no);
					order.setPayType(SundayCommonConstants.pay_type_alipay);
					order.setPayFrontType(2);
					//order.setWechatPayAmount(price);
					orderService.update(order);
					//执行订单回调,处理拼团逻辑
					orderService.callback(order);
				}
			}
		}

		//2.2，余额充值
		if(pay.getType()== SundayCommonConstants.pay_order_type_income){/*
			List<Long> incomeRecordIds = new ArrayList<Long>();
			for(String incomeRecordIdStr:pay.getOrderIds().split("_")){
				incomeRecordIds.add(Long.valueOf(incomeRecordIdStr));
			}
			if(ListUtil.isNull(incomeRecordIds)){
				logger.error("支付-支付宝-回掉-本地预支付记录无充值记录参数，返回");
				alipayWapResult.setVerify_result(false);
				return alipayWapResult;
			}
			param.clear();
			param.put("status",0);
			param.put("ids",incomeRecordIds);
			List<KitchenIncomeRecord> incomeRecords =incomeRecordMapper.select(param);
			//校验付款金额。只校验充值的金额，不校验赠送的
			Double thisAmount=0.00;//充值金额
			Long memberId=0l;//充值用户ID

			for(KitchenIncomeRecord incomeRecord:incomeRecords){
				if(incomeRecord.getType()== SundayCommonConstants.income_record_type_charge&&
						incomeRecord.getAmount().compareTo(price)==1){
					logger.error("支付-支付宝-回掉-余额充值实际支付金额错误，应支付金额="+incomeRecord.getAmount()+
							"，实际支付金额="+price+"，充值记录ID="+incomeRecord.getId()+",预支付订单编号="+out_trade_no);
					alipayWapResult.setVerify_result(false);
					return alipayWapResult;
				}
				//2017年8月25日新增
				if(LongUtil.isZreo(memberId)){
					memberId=incomeRecord.getMemberId();
				}
				//实得金额=充值金额+赠送金额
				thisAmount+=incomeRecord.getAmount().doubleValue();
			}
			//更新充值状态，修改用户钱包
			logger.info("支付-支付宝-回掉-余额充值-修改钱包信息-开始");
			//incomeService.generateRecord(null,,String orderNo,BigDecimal payAmount,List<KitchenIncomeRecord> incomeRecords,String chargeNo))
			//更改充值记录状态
			memberService.changeBalance(memberId,
					SundayCommonConstants.income_record_type_charge,
					null,
					new BigDecimal(thisAmount).setScale(2,BigDecimal.ROUND_HALF_UP),
					incomeRecords,
					out_trade_no);
			logger.info("支付-支付宝-回掉-余额充值-修改钱包信息-结束");*/
		}

		alipayWapResult.setVerify_result(verify_result);

		return alipayWapResult;
	}
	/**
	 * 微信支付回掉（含开放平台和服务号支付）
	 * @param request
	 * @param response
	 */
	public String callback_wechat(HttpServletRequest request, HttpServletResponse response)throws Exception{
		//AlipayWapResult alipayWapResult=new AlipayWapResult();

		String callback_wechat_msg="success";
		//1，检验签名和请求来源
		DataInputStream in = new DataInputStream(request.getInputStream());
		byte[] dataOrigin = new byte[request.getContentLength()];
		in.readFully(dataOrigin); // 根据长度，将消息实体的内容读入字节数组dataOrigin中
		if(null != in){
			in.close(); // 关闭数据流
		}
		String wxNotifyXml = new String(dataOrigin);
		Map<String, String> params = XMLUtil.doXMLParse(wxNotifyXml);
		logger.info("00000---------weixincallbakcparam--------开始-----");
		for (String key : params.keySet()) {
			logger.info("------微信OPEN回掉返回的参数key = " + key + " and ---------value = " + params.get(key));
		}
		logger.info("00000---------weixincallbakcparam--------结束-----");
		//
		Map<String,Object> param = new HashMap<String,Object>();
		param.put("type", SundayCommonConstants.pay_type_wechatpay_open);
		List<SundayPayConfig> payConfigs =payConfigMapper.select(param);
		//微信API
		String wechatApi = "";
		if(ListUtil.isNull(payConfigs)){
			return "fail";
		}
		//微信API
		wechatApi=payConfigs.get(0).getWeChatApi();
		//校验签名
		boolean isSign= WXPayNotify.verifyNotify(params,wechatApi);
		logger.info("-------------------微信-open-回掉-签名校验实际结果--"+isSign);
		//2017年6月14日，零时不校验签名
		isSign=true;
		if(!isSign){
			logger.error("支付微信-open-回掉-签名验证失败。");
			return "fail";
		}


		String  trade_status=params.get("result_code");
		String  out_trade_no=params.get("out_trade_no");
		String trade_no = params.get("transaction_id");

		//微信返回的是分(金融单位)
		String  total_fee =params.get("total_fee");
		logger.info("支付-微信-open-回掉-信息.trade_status="+trade_status+
				",out_trade_no="+out_trade_no+
				",trade_no="+trade_no+

				",total_fee="+total_fee
				);


		//查询本地预支付记录
		param.clear();
		if(StringUtils.isEmpty(out_trade_no)){
			logger.error("支付-微信-open-回掉-外部订单为空");
			return "fail";
		}
		param.put("orderNo",out_trade_no);
		List<SundayPay> pays = super.select(param);
		if(ListUtil.isNull(pays)){
			logger.error("支付-微信-open-回掉-本地无预支付记录，返回");
			return "fail";
		}
		SundayPay pay=pays.get(0);
		//2，项目内部逻辑。校验支付金额
		//2.1,订单消费
		//校验付款金额。微信返回的是分（金额单位）
		BigDecimal price=new BigDecimal(Double.valueOf(total_fee)/100).setScale(2,BigDecimal.ROUND_HALF_UP);
		if(pay.getType()== SundayCommonConstants.pay_order_type_order){
			List<Long> orderIds = new ArrayList<Long>();
			for(String orderIdStr:pay.getOrderIds().split("_")){
				orderIds.add(Long.valueOf(orderIdStr));
			}
			if(ListUtil.isNull(orderIds)){
				logger.error("支付-微信-回掉-本地预支付记录无订单参数，返回");

				return "fail";
			}
		/*	param.clear();
			param.put("status",SundayCommonConstants.ORDER_STATUS_DFK);
			param.put("ids",orderIds);
			List<SundayOrder> orders =orderMapper.select(param);*/
			//校验付款金额。微信返回的是分（金额单位）
			Double orderPayAmount = 0.00;
			param.clear();
			param.put("ids",orderIds);
			List<SundayOrder> orders =orderService.select(param);
			for(SundayOrder order:orders){
				orderPayAmount+=order.getPayAmount().doubleValue();
			}
			if(price.compareTo(new BigDecimal(orderPayAmount).setScale(2,BigDecimal.ROUND_HALF_UP))==-1){
				logger.error("支付-微信-回掉-本地订单实付金额和实际回掉金额有误-此操作标识有人非法刷单，本地订单实付金额="+orderPayAmount+",微信回掉金额="+price);
				return "fail";
			}
			//更改订单状态
			List<Long> memberIds =new ArrayList<Long>();
			for(SundayOrder order:orders){
				//避免重复回掉
				if(order.getStatus()== SundayCommonConstants.ORDER_STATUS_DFK){
					Integer status= SundayCommonConstants.ORDER_STATUS_DFH;
					logger.info("支付-微信-回掉-当前支付订单"+order.getOrderNo());
					if(order.getType()==SundayCommonConstants.type_pintuan){
						//0单独购买，1参与别人的，2自己开团
						if(order.getTeamIsJoin()==0){
							status=SundayCommonConstants.ORDER_STATUS_DFH;//待发货
						}else{
							status=SundayCommonConstants.ORDER_STATUS_DPT;//待拼团；
						}
					}else{
						//2018年2月24日，根据配送方式判断
						//门店配送为待配送
						if(order.getSendType()==SundayCommonConstants.send_type_send){
							status=SundayCommonConstants.ORDER_STATUS_DFH;//待发货
							//自提为配送中
						}else if(order.getSendType()==SundayCommonConstants.send_type_self){
							status=SundayCommonConstants.ORDER_STATUS_PSZ;//配送中
						}
					}
					order.setStatus(status);
					order.setPayTime(new Date());
					order.setPayNo(trade_no);
					order.setPayType(SundayCommonConstants.pay_type_wechatpay_open);
					order.setPayFrontType(2);
					//order.setWechatPayAmount(price);
					orderService.update(order);
					//执行订单回调,处理拼团逻辑
					orderService.callback(order);
				}
			}
			/*//推送订单消息
			if(ListUtil.isNotNull(memberIds)){
				List<SundayCid> cids = cidService.findByMemberId(null,memberIds);
				for(SundayCid cid:cids){
					GeTuiUtil.sendMessage(cid,
							"您有新的花果山果蔬订单需要配送", 1,null);
				}

			}*/
		}

		//2.2，余额充值
		if(pay.getType()== SundayCommonConstants.pay_order_type_income){
			/*List<Long> incomeRecordIds = new ArrayList<Long>();
			for(String incomeRecordIdStr:pay.getOrderIds().split("_")){
				incomeRecordIds.add(Long.valueOf(incomeRecordIdStr));
			}
			if(ListUtil.isNull(incomeRecordIds)){
				logger.error("支付-支付宝-回掉-本地预支付记录无充值记录参数，返回");
				return "fail";
			}
			param.clear();
			param.put("status",0);
			param.put("ids",incomeRecordIds);
			List<KitchenIncomeRecord> incomeRecords =incomeRecordMapper.select(param);
			//校验付款金额。只校验充值的金额，不校验赠送的
			Double thisAmount=0.00;//充值金额
			Long memberId=0l;//充值用户ID
			for(KitchenIncomeRecord incomeRecord:incomeRecords){
				if(incomeRecord.getType()== SundayCommonConstants.income_record_type_charge&&
						incomeRecord.getAmount().compareTo(price)==1){
					logger.error("支付-微信-回掉-余额充值实际支付金额错误，应支付金额="+incomeRecord.getAmount()+
							"，实际支付金额="+price+"，充值记录ID="+incomeRecord.getId()+",预支付订单编号="+out_trade_no);

					return "fail";
				}
				//2017年8月25日新增
				if(LongUtil.isZreo(memberId)){
					memberId=incomeRecord.getMemberId();
				}
				//实得金额=充值金额+赠送金额
				thisAmount+=incomeRecord.getAmount().doubleValue();
			}
			logger.info("支付-支微信-回掉-余额充值-修改钱包信息-开始");
			memberService.changeBalance(memberId,
					SundayCommonConstants.income_record_type_charge,
					null,
					new BigDecimal(thisAmount).setScale(2,BigDecimal.ROUND_HALF_UP),
					incomeRecords,
					out_trade_no);

			logger.info("支付-支微信-回掉-余额充值-修改钱包信息-结束");*/

		}
		return callback_wechat_msg;

	}

	/**
	 * 回掉验证成功后执行的业务逻辑
	 */
	public void callback_logic(){

	}
}
